import json
from pyecharts.charts import Pie, Bar, TreeMap, Liquid, Grid
from pyecharts import options as opts

# from pyecharts.globals import SymbolType
from pyecharts.commons.utils import JsCode
# from pyecharts.charts import *
class ClassificationModel:
    def __init__(self, file_path):
        #初始化文件名
        self.file_path = file_path
        self.data = self.load_data()
        self.total_nums = 0
        self.results_count = {}
        self.labels = []
        self.counts = []
        self.results_label = [[] for _ in range(6)]
        self.x = "600px"
        self.y = "400px"
        self.f = 60

    def load_data(self):
        #读取文件
        with open(self.file_path, 'r') as file:
            data = json.load(file)
        return data

    def get_classification_result(self, x):
        #得到样本x对应的分类结果，没有则返回None
        if x in self.data:
            return self.data[x]
        else:
            return None


    def classify(self, x):
        #输出x对应的分类结果
        result = self.get_classification_result(x)
        print(result)

    def get_total_nums(self):
        # 输出样本总数
        # print(self.total_nums)
        return self.total_nums

    def count_and_plot_results(self):
        # 处理数据，在画图前要先调用该函数
        for i in range(6):
            self.results_count[i] = 0
        for result in self.data.values():
            self.results_count[result] += 1
        for key, value in self.data.items():
            self.results_label[value].append(key)

        # print(self.results_label[1])

        sorted_results = dict(sorted(self.results_count.items()))
        self.labels = ["正常", "故障1", "故障2", "故障3", "故障4", "故障5"]
        self.counts = list(sorted_results.values())
        self.total_nums = sum(self.counts)

    def generate_dict(self):
        # 去掉第一个值
        new_labels = self.labels[1:]
        new_counts = self.counts[1:]

        # 将 new_labels 和 new_counts 按照 new_counts 排序
        sorted_indexes = sorted(range(len(new_counts)), key=lambda k: new_counts[k], reverse=True)
        new_labels = [new_labels[i] for i in sorted_indexes]
        new_counts = [new_counts[i] for i in sorted_indexes]

        for i in range(5):
            new_counts[i] /= self.total_nums

        # 生成字典
        data_dict = {
            'labels': new_labels,
            'counts': new_counts
        }

        return data_dict

    def bar_plot(self, output_path):
        # 直方图
        # color_function = """
        #         function (params) {
        #             if(params.key=='0') return #3ddcac;
        #             if(params.key=='1') return #5b93ab;
        #             if(params.key=='2') return #a5a5a5;
        #             if(params.key=='3') return #36ccdc;
        #             if(params.key=='4') return #fb8609;
        #             if(params.key=='5') return #f4145c;
        #         }
        #         """

        colors = ['#3ddcac', '#5b93ab', '#a5a5a5', '#36ccdc', '#fb8609', '#f4145c']
        # bar = (Bar(init_opts=opts.InitOpts(width="400px", height="400px"))
        #         .add_xaxis(self.labels)
        #         .add_yaxis("", self.counts, itemstyle_opts=opts.ItemStyleOpts(color=JsCode(color_function)))
        # )

        # bar = Bar(init_opts=opts.InitOpts(width="400px", height="400px"))
        # # bar.add_xaxis(self.labels)
        # for i in range(6):
        #     bar.add_xaxis([self.labels[i]])
        #     bar.add_yaxis('', [self.counts[i]], itemstyle_opts=opts.ItemStyleOpts(color=colors[i]))

        bar = (Bar(init_opts=opts.InitOpts(width="400px", height="400px"))
                .add_xaxis(self.labels)
                .add_yaxis("", self.counts)
                .set_global_opts(title_opts=opts.TitleOpts(title="结果直方图", pos_left="center"))
                .set_series_opts(
                    # 标签配置项
                    # label_opts=opts.LabelOpts(
                    #     is_show=True,
                    #     color="#06F6F8"
                    # ),
                    # 图元样式配置项
                    itemstyle_opts={
                        # 线性渐变，参考：https://pyecharts.org/#/zh-cn/series_options?id=itemstyleopts
                        # 前四个参数分别是 x0, y0, x2, y2, 范围从 0 - 1，相当于在图形包围盒中的百分比，
                        # 如果 globalCoord 为 `true`，则该四个值是绝对的像素位置
                        "color": {
                            "type": 'linear',
                            "x": 0,
                            "y": 0,
                            "x2": 0,
                            "y2": 1,
                            "colorStops": [{
                                "offset": 0, "color": '#0781C3'  # 蓝色（头部）
                            }, {
                                "offset": 1, "color": '#06F6F8'  # 青色（底部）
                            }],
                        },
                    }
            )
        )
        bar.render(output_path)

    def pie_plot_2(self, output_path):
        # 扇形-玫瑰图
        colors = ['#3ddcac', '#5b93ab', '#a5a5a5', '#36ccdc', '#fb8609', '#f4145c']
        pie = (
            Pie(init_opts=opts.InitOpts(width="600px", height="400px"))
            #init_opts=opts.InitOpts(width="300px", height="300px")
                .add(
                    series_name="玫瑰图",
                    data_pair=[list(z) for z in zip(self.labels, self.counts)],
                    radius=["30%", "75%"],  # 控制玫瑰图的半径范围，从内到外
                    center=["50%", "50%"],  # 控制玫瑰图的位置
                    rosetype="radius",  # 设置玫瑰图的类型，radius 表示通过半径来控制角度
                    # itemstyle_opts=opts.ItemStyleOpts(color=colors)  # 设置扇形的颜色
                )
                .set_series_opts(
                    label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
                .set_colors(colors)
                .set_global_opts(
                legend_opts=opts.LegendOpts(orient="horizontal", pos_top="top", padding=0))
                # title_opts=opts.TitleOpts(title="扇形图", pos_left="center"))
                )
        pie.render(output_path)

    def treemap_plot(self, output_path):
        # 面积分割图
        colors = ['#44dbb4', '#5b93ab', '#c1c2c4', '#36ccdc', '#fb870a', '#f4145c']
        # merged_dict = dict(sorted(zip(self.labels, self.counts, colors), key=lambda x: x[1]))
        # 拆分为两个列表
        sorted_data = sorted(zip(self.labels, self.counts, colors), key=lambda x: x[1], reverse=True)
        sorted_labels, sorted_counts, sorted_colors = zip(*sorted_data)

        treemap = TreeMap(init_opts=opts.InitOpts(width="400px", height="400px"))
        data = [
            {"value": sorted_counts[0], "name": sorted_labels[0]},
            {"value": sorted_counts[1], "name": sorted_labels[1]},
            {"value": sorted_counts[2], "name": sorted_labels[2]},
            {"value": sorted_counts[3], "name": sorted_labels[3]},
            {"value": sorted_counts[4], "name": sorted_labels[4]},
            {"value": sorted_counts[5], "name": sorted_labels[5]},
        ]
        treemap.add("", data, leaf_depth=1)
        treemap.set_colors(sorted_colors)
        treemap.set_global_opts(title_opts=opts.TitleOpts(title="面积分割图", pos_left="center"))
        treemap.render(output_path)

    def liquid(self, index, output_path):
        # 水球图
        liquid = (
            Liquid(init_opts=opts.InitOpts(width=self.x, height=self.y))
                .add("", [(self.counts[index]) / (self.total_nums)],
                        label_opts=opts.LabelOpts(
                        font_size=self.f,  # 默认50
                        formatter=JsCode(
                            """function (param) {
                                return (Math.floor(param.value * 100000) / 1000) + '%'; 
                            }"""
                        ),
                        position="inside"))
            )
        # 渲染图表
        liquid.render(output_path)

    def liquid0(self, output_path):
        # 水球图
        liquid = (
            Liquid(init_opts=opts.InitOpts(width=self.x, height=self.y))
            .add("", [(self.counts[0])/(self.total_nums)],
                 label_opts=opts.LabelOpts(
                     font_size=self.f,  # 默认50
                     formatter=JsCode(
                         """function (param) {
                             return (Math.floor(param.value * 100000) / 1000) + '%'; 
                         }"""
                     ),
                     position="inside"))
        )
        # 渲染图表
        liquid.render(output_path)

    def liquid1(self, output_path):
        # 水球图
        liquid = (
            Liquid(init_opts=opts.InitOpts(width=self.x, height=self.y))
            .add("", [(self.counts[1])/(self.total_nums)],
                 label_opts=opts.LabelOpts(
                     font_size=self.f,  # 默认50
                     formatter=JsCode(
                         """function (param) {
                             return (Math.floor(param.value * 100000) / 1000) + '%'; 
                         }"""
                     ),
                     position="inside"))
        )
        # 渲染图表
        liquid.render(output_path)

    def liquid2(self, output_path):
        # 水球图
        liquid = (
            Liquid(init_opts=opts.InitOpts(width=self.x, height=self.y))
            .add("", [(self.counts[2])/(self.total_nums)],
                 label_opts=opts.LabelOpts(
                     font_size=self.f,  # 默认50
                     formatter=JsCode(
                         """function (param) {
                             return (Math.floor(param.value * 100000) / 1000) + '%'; 
                         }"""
                     ),
                     position="inside"))
        )
        # 渲染图表
        liquid.render(output_path)

    def liquid3(self, output_path):
        # 水球图
        liquid = (
            Liquid(init_opts=opts.InitOpts(width=self.x, height=self.y))
            .add("", [(self.counts[3])/(self.total_nums)],
                 label_opts=opts.LabelOpts(
                     font_size=self.f,  # 默认50
                     formatter=JsCode(
                         """function (param) {
                             return (Math.floor(param.value * 100000) / 1000) + '%'; 
                         }"""
                     ),
                     position="inside"))
        )
        # 渲染图表
        liquid.render(output_path)

    def liquid4(self, output_path):
        # 水球图
        liquid = (
            Liquid(init_opts=opts.InitOpts(width=self.x, height=self.y))
            .add("", [(self.counts[4])/(self.total_nums)],
                 label_opts=opts.LabelOpts(
                     font_size=self.f,  # 默认50
                     formatter=JsCode(
                         """function (param) {
                             return (Math.floor(param.value * 100000) / 1000) + '%'; 
                         }"""
                     ),
                     position="inside"))
        )
        # 渲染图表
        liquid.render(output_path)

    def liquid5(self, output_path):
        # 水球图
        liquid = (
            Liquid(init_opts=opts.InitOpts(width=self.x, height=self.y))
            .add("", [(self.counts[5])/(self.total_nums)],
                 label_opts=opts.LabelOpts(
                     font_size=self.f,  # 默认50
                     formatter=JsCode(
                         """function (param) {
                             return (Math.floor(param.value * 100000) / 1000) + '%'; 
                         }"""
                     ),
                     position="inside"))
        )
        # 渲染图表
        liquid.render(output_path)

# # validate_1000_y_true.json  换成想知道的json文件名
# model = ClassificationModel('validate_1000_y_true.json')
#
# # 处理数据，在画图前一定要调用
# model.count_and_plot_results()
#
# # 得到样本总数
# model.get_total_nums()
#
# # 直方图
# model.bar_plot("D:/qq/backends/static/html_tmp_1/bar.html")
#
# # 扇形图-玫瑰图
# model.pie_plot_2("D:/qq/backends/static/html_tmp_1/pie2.html")
#
# # 面积分割图
# model.treemap_plot("D:/qq/backends/static/html_tmp_1/treemap.html")
#
# # 水球图
# model.liquid0("D:/qq/backends/static/html_tmp_1/liquid0.html")
# model.liquid1("D:/qq/backends/static/html_tmp_1/liquid1.html")
# model.liquid2("D:/qq/backends/static/html_tmp_1/liquid2.html")
# model.liquid3("D:/qq/backends/static/html_tmp_1/liquid3.html")
# model.liquid4("D:/qq/backends/static/html_tmp_1/liquid4.html")
# model.liquid5("D:/qq/backends/static/html_tmp_1/liquid5.html")
#
